/*
 *  Copyright (C) 2008      Tri Tech Information Systems Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "default_visitor.h"

#include <boost/python.hpp>
using namespace boost::python;

void Wrap_Visitor();

#define PYXX_VISITOR_OVERRIDE( _name, _arg ) \
    virtual void _name(_arg* a) \
    { \
        if( override f = this->get_override(#_name) ) \
            f( a ); \
        DefaultVisitor::_name( a ); \
    }

#define PYXX_VISITOR_DEF( _name ) \
    .def( #_name, &_Visitor::_name, &DefaultVisitor::_name )


struct _Visitor :
    public DefaultVisitor,
    wrapper< DefaultVisitor >
{
    static void Wrap_Visitor()
    {
        class_< _Visitor, boost::noncopyable >( "Visitor" )
//            .def( "visit", &DefaultVisitor::visit )
            PYXX_VISITOR_DEF( visitAccessSpecifier )
            PYXX_VISITOR_DEF( visitAsmDefinition )
            PYXX_VISITOR_DEF( visitBaseClause )
            PYXX_VISITOR_DEF( visitBaseSpecifier )
            PYXX_VISITOR_DEF( visitBinaryExpression )
            PYXX_VISITOR_DEF( visitCastExpression )
            PYXX_VISITOR_DEF( visitClassMemberAccess )
            PYXX_VISITOR_DEF( visitClassSpecifier )
            PYXX_VISITOR_DEF( visitCompoundStatement )
            PYXX_VISITOR_DEF( visitCondition )
            PYXX_VISITOR_DEF( visitConditionalExpression )
            PYXX_VISITOR_DEF( visitCppCastExpression )
            PYXX_VISITOR_DEF( visitCtorInitializer )
            PYXX_VISITOR_DEF( visitDeclarationStatement )
            PYXX_VISITOR_DEF( visitDeclarator )
            PYXX_VISITOR_DEF( visitDeleteExpression )
            PYXX_VISITOR_DEF( visitDoStatement )
            PYXX_VISITOR_DEF( visitElaboratedTypeSpecifier )
            PYXX_VISITOR_DEF( visitEnumSpecifier )
            PYXX_VISITOR_DEF( visitEnumerator )
            PYXX_VISITOR_DEF( visitExceptionSpecification )
            PYXX_VISITOR_DEF( visitExpressionOrDeclarationStatement )
            PYXX_VISITOR_DEF( visitExpressionStatement )
            PYXX_VISITOR_DEF( visitForStatement )
            PYXX_VISITOR_DEF( visitFunctionCall )
            PYXX_VISITOR_DEF( visitFunctionDefinition )
            PYXX_VISITOR_DEF( visitIfStatement )
            PYXX_VISITOR_DEF( visitIncrDecrExpression )
            PYXX_VISITOR_DEF( visitInitDeclarator )
            PYXX_VISITOR_DEF( visitInitializer )
            PYXX_VISITOR_DEF( visitInitializerClause )
            PYXX_VISITOR_DEF( visitLabeledStatement )
            PYXX_VISITOR_DEF( visitLinkageBody )
            PYXX_VISITOR_DEF( visitLinkageSpecification )
            PYXX_VISITOR_DEF( visitMemInitializer )
            PYXX_VISITOR_DEF( visitName )
            PYXX_VISITOR_DEF( visitNamespace )
            PYXX_VISITOR_DEF( visitNamespaceAliasDefinition )
            PYXX_VISITOR_DEF( visitNewDeclarator )
            PYXX_VISITOR_DEF( visitNewExpression )
            PYXX_VISITOR_DEF( visitNewInitializer )
            PYXX_VISITOR_DEF( visitNewTypeId )
            PYXX_VISITOR_DEF( visitOperator )
            PYXX_VISITOR_DEF( visitOperatorFunctionId )
            PYXX_VISITOR_DEF( visitParameterDeclaration )
            PYXX_VISITOR_DEF( visitParameterDeclarationClause )
            PYXX_VISITOR_DEF( visitPostfixExpression )
            PYXX_VISITOR_DEF( visitPrimaryExpression )
            PYXX_VISITOR_DEF( visitPtrOperator )
            PYXX_VISITOR_DEF( visitPtrToMember )
            PYXX_VISITOR_DEF( visitReturnStatement )
            PYXX_VISITOR_DEF( visitSimpleDeclaration )
            PYXX_VISITOR_DEF( visitSimpleTypeSpecifier )
            PYXX_VISITOR_DEF( visitSizeofExpression )
            PYXX_VISITOR_DEF( visitStringLiteral )
            PYXX_VISITOR_DEF( visitSubscriptExpression )
            PYXX_VISITOR_DEF( visitSwitchStatement )
            PYXX_VISITOR_DEF( visitTemplateArgument )
            PYXX_VISITOR_DEF( visitTemplateDeclaration )
            PYXX_VISITOR_DEF( visitTemplateParameter )
            PYXX_VISITOR_DEF( visitThrowExpression )
            PYXX_VISITOR_DEF( visitTranslationUnit )
            PYXX_VISITOR_DEF( visitTryBlockStatement )
            PYXX_VISITOR_DEF( visitTypeId )
            PYXX_VISITOR_DEF( visitTypeIdentification )
            PYXX_VISITOR_DEF( visitTypeParameter )
            PYXX_VISITOR_DEF( visitTypedef )
            PYXX_VISITOR_DEF( visitUnaryExpression )
            PYXX_VISITOR_DEF( visitUnqualifiedName )
            PYXX_VISITOR_DEF( visitUsing )
            PYXX_VISITOR_DEF( visitUsingDirective )
            PYXX_VISITOR_DEF( visitWhileStatement )
            PYXX_VISITOR_DEF( visitWinDeclSpec )
            ;
    }

    PYXX_VISITOR_OVERRIDE( visitAccessSpecifier, AccessSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitAsmDefinition, AsmDefinitionAST )
    PYXX_VISITOR_OVERRIDE( visitBaseClause, BaseClauseAST )
    PYXX_VISITOR_OVERRIDE( visitBaseSpecifier, BaseSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitBinaryExpression, BinaryExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitCastExpression, CastExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitClassMemberAccess, ClassMemberAccessAST )
    PYXX_VISITOR_OVERRIDE( visitClassSpecifier, ClassSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitCompoundStatement, CompoundStatementAST )
    PYXX_VISITOR_OVERRIDE( visitCondition, ConditionAST )
    PYXX_VISITOR_OVERRIDE( visitConditionalExpression, ConditionalExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitCppCastExpression, CppCastExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitCtorInitializer, CtorInitializerAST )
    PYXX_VISITOR_OVERRIDE( visitDeclarationStatement, DeclarationStatementAST )
    PYXX_VISITOR_OVERRIDE( visitDeclarator, DeclaratorAST )
    PYXX_VISITOR_OVERRIDE( visitDeleteExpression, DeleteExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitDoStatement, DoStatementAST )
    PYXX_VISITOR_OVERRIDE( visitElaboratedTypeSpecifier, ElaboratedTypeSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitEnumSpecifier, EnumSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitEnumerator, EnumeratorAST )
    PYXX_VISITOR_OVERRIDE( visitExceptionSpecification, ExceptionSpecificationAST )
    PYXX_VISITOR_OVERRIDE( visitExpressionOrDeclarationStatement,
                            ExpressionOrDeclarationStatementAST )
    PYXX_VISITOR_OVERRIDE( visitExpressionStatement, ExpressionStatementAST )
    PYXX_VISITOR_OVERRIDE( visitForStatement, ForStatementAST )
    PYXX_VISITOR_OVERRIDE( visitFunctionCall, FunctionCallAST )
    PYXX_VISITOR_OVERRIDE( visitFunctionDefinition, FunctionDefinitionAST )
    PYXX_VISITOR_OVERRIDE( visitIfStatement, IfStatementAST )
    PYXX_VISITOR_OVERRIDE( visitIncrDecrExpression, IncrDecrExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitInitDeclarator, InitDeclaratorAST )
    PYXX_VISITOR_OVERRIDE( visitInitializer, InitializerAST )
    PYXX_VISITOR_OVERRIDE( visitInitializerClause, InitializerClauseAST )
    PYXX_VISITOR_OVERRIDE( visitLabeledStatement, LabeledStatementAST )
    PYXX_VISITOR_OVERRIDE( visitLinkageBody, LinkageBodyAST )
    PYXX_VISITOR_OVERRIDE( visitLinkageSpecification, LinkageSpecificationAST )
    PYXX_VISITOR_OVERRIDE( visitMemInitializer, MemInitializerAST )
    PYXX_VISITOR_OVERRIDE( visitName, NameAST )
    PYXX_VISITOR_OVERRIDE( visitNamespace, NamespaceAST )
    PYXX_VISITOR_OVERRIDE( visitNamespaceAliasDefinition, NamespaceAliasDefinitionAST )
    PYXX_VISITOR_OVERRIDE( visitNewDeclarator, NewDeclaratorAST )
    PYXX_VISITOR_OVERRIDE( visitNewExpression, NewExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitNewInitializer, NewInitializerAST )
    PYXX_VISITOR_OVERRIDE( visitNewTypeId, NewTypeIdAST )
    PYXX_VISITOR_OVERRIDE( visitOperator, OperatorAST )
    PYXX_VISITOR_OVERRIDE( visitOperatorFunctionId, OperatorFunctionIdAST )
    PYXX_VISITOR_OVERRIDE( visitParameterDeclaration, ParameterDeclarationAST )
    PYXX_VISITOR_OVERRIDE( visitParameterDeclarationClause,
                            ParameterDeclarationClauseAST )
    PYXX_VISITOR_OVERRIDE( visitPostfixExpression, PostfixExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitPrimaryExpression, PrimaryExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitPtrOperator, PtrOperatorAST )
    PYXX_VISITOR_OVERRIDE( visitPtrToMember, PtrToMemberAST )
    PYXX_VISITOR_OVERRIDE( visitReturnStatement, ReturnStatementAST )
    PYXX_VISITOR_OVERRIDE( visitSimpleDeclaration, SimpleDeclarationAST )
    PYXX_VISITOR_OVERRIDE( visitSimpleTypeSpecifier, SimpleTypeSpecifierAST )
    PYXX_VISITOR_OVERRIDE( visitSizeofExpression, SizeofExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitStringLiteral, StringLiteralAST )
    PYXX_VISITOR_OVERRIDE( visitSubscriptExpression, SubscriptExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitSwitchStatement, SwitchStatementAST )
    PYXX_VISITOR_OVERRIDE( visitTemplateArgument, TemplateArgumentAST )
    PYXX_VISITOR_OVERRIDE( visitTemplateDeclaration, TemplateDeclarationAST )
    PYXX_VISITOR_OVERRIDE( visitTemplateParameter, TemplateParameterAST )
    PYXX_VISITOR_OVERRIDE( visitThrowExpression, ThrowExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitTranslationUnit, TranslationUnitAST )
    PYXX_VISITOR_OVERRIDE( visitTryBlockStatement, TryBlockStatementAST )
    PYXX_VISITOR_OVERRIDE( visitTypeId, TypeIdAST )
    PYXX_VISITOR_OVERRIDE( visitTypeIdentification, TypeIdentificationAST )
    PYXX_VISITOR_OVERRIDE( visitTypeParameter, TypeParameterAST )
    PYXX_VISITOR_OVERRIDE( visitTypedef, TypedefAST )
    PYXX_VISITOR_OVERRIDE( visitUnaryExpression, UnaryExpressionAST )
    PYXX_VISITOR_OVERRIDE( visitUnqualifiedName, UnqualifiedNameAST )
    PYXX_VISITOR_OVERRIDE( visitUsing, UsingAST )
    PYXX_VISITOR_OVERRIDE( visitUsingDirective, UsingDirectiveAST )
    PYXX_VISITOR_OVERRIDE( visitWhileStatement, WhileStatementAST )
    PYXX_VISITOR_OVERRIDE( visitWinDeclSpec, WinDeclSpecAST )
};


void Wrap_Visitor()
{
    _Visitor::Wrap_Visitor();
}
